package com.whfc.safety.service.impl;

import com.whfc.common.exception.BizException;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.RegexUtil;
import com.whfc.safety.dao.SafetyPartMapper;
import com.whfc.safety.dto.SafetyPartDTO;
import com.whfc.safety.dto.SafetyPartImportDTO;
import com.whfc.safety.dto.SafetyPartImportResultDTO;
import com.whfc.safety.entity.SafetyPart;
import com.whfc.safety.param.SafetyPartAddParam;
import com.whfc.safety.param.SafetyPartEditParam;
import com.whfc.safety.service.SafetyPartService;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClasssName SafetyPartServiceImpl
 * @Description 安全问题部位实现类
 * @Author hw
 * @Date 2020/8/6 9:17
 * @Version 1.0
 */
@DubboService(interfaceClass = SafetyPartService.class, version = "1.0.0", timeout = 5000)
public class SafetyPartServiceImpl implements SafetyPartService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SafetyPartMapper safetyPartMapper;

    @Override
    public List<SafetyPartDTO> list(Integer deptId, String keyword) throws BizException {
        logger.info("查询安全部位列表，deptId:{}，keyword:{}", deptId, keyword);
        List<SafetyPartDTO> list = safetyPartMapper.selectSafetyPartDTOList(deptId, keyword);
        return parseTree(list);
    }

    @Override
    public void add(SafetyPartAddParam addParam) throws BizException {
        logger.info("新增安全部位，SafetyPartAddParam:{}", addParam);
        Integer pid = addParam.getPid();
        SafetyPart part = new SafetyPart();
        String code = addParam.getCode();
        if (!RegexUtil.isInteger(code)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "编码格式错误.");
        }
        if (pid != null) {
            SafetyPart safetyPart = safetyPartMapper.selectByPrimaryKey(pid);
            if (safetyPart == null) {
                throw new BizException(ResultEnum.FAILURE.getCode(), "父检测部位不存在.");
            }
            code = safetyPart.getCode() + "." + code;
            part.setPid(safetyPart.getId());
        } else {
            part.setPid(0);
        }
        SafetyPart safetyPart = safetyPartMapper.selectPartByCode(code, addParam.getDeptId());
        if (safetyPart != null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该编码已存在.");
        }
        part.setCode(code);
        part.setDeptId(addParam.getDeptId());
        part.setName(addParam.getName());
        safetyPartMapper.insertSelective(part);
    }

    @Override
    public void edit(SafetyPartEditParam editParam) throws BizException {
        logger.info("修改安全部位，SafetyPartEditParam:{}", editParam);
        String code = editParam.getCode();
        if (!RegexUtil.isInteger(code)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "编码格式错误.");
        }
        SafetyPart safetyPart = safetyPartMapper.selectByPrimaryKey(editParam.getPartId());
        if (safetyPart == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该检测部位不存在.");
        }
        SafetyPart prentPart = safetyPartMapper.selectByPrimaryKey(safetyPart.getPid());

        if (prentPart != null) {
            code = prentPart.getCode() + "." + code;
        }
        SafetyPart part = safetyPartMapper.selectPartByCode(code, safetyPart.getDeptId());
        Integer length = safetyPart.getCode().length();
        if (part != null && !safetyPart.getCode().equals(code)) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该编码已存在.");
        }
        List<SafetyPart> parts = safetyPartMapper.selectLikeCode(safetyPart.getCode() + ".");
        for (SafetyPart lowPart : parts) {
            lowPart.setCode(code + lowPart.getCode().substring(length));
            safetyPartMapper.updateByPrimaryKeySelective(lowPart);
        }
        safetyPartMapper.updateNameById(editParam.getPartId(), code, editParam.getName());
    }


    @Override
    public void del(Integer partId) throws BizException {
        logger.info("删除安全部位，partId:{}", partId);
        if (!safetyPartMapper.selectByPid(partId).isEmpty()) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "有子节点存在无法删除.");
        }
        safetyPartMapper.logicDel(partId);
    }

    @Override
    public SafetyPartImportResultDTO importPart(Integer deptId, List<SafetyPartImportDTO> list) {
        try {
            logger.info("导入安全部位，deptId:{}，List<SafetyPartImportDTO>:{}", deptId, list);
            //取出所有的编码
            List<String> codeList = safetyPartMapper.selectCodeList(deptId);
            //数据处理
            int successNumber = 0;
            int failedNumber = 0;
            for (SafetyPartImportDTO importParam : list) {
                String code = importParam.getCode();
                if (code == null) {
                    importParam.setResult("编码错误");
                    failedNumber += 1;
                    continue;
                }
                if (codeList.contains(code)) {
                    importParam.setResult("编码已存在.");
                    failedNumber += 1;
                    continue;
                }
                SafetyPart part = new SafetyPart();
                part.setDeptId(deptId);
                part.setCode(code);
                part.setName(importParam.getName());
                if (code.contains(".")) {
                    String parentCode = code.substring(0, code.lastIndexOf("."));
                    if (!codeList.contains(parentCode)) {
                        importParam.setResult("父节点编码不存在.");
                        failedNumber += 1;
                        continue;
                    }
                    SafetyPart parentPart = safetyPartMapper.selectPartByCode(parentCode, deptId);
                    part.setPid(parentPart.getId());
                } else {
                    part.setPid(0);
                }
                safetyPartMapper.insertSelective(part);
                codeList.add(code);
                successNumber += 1;
            }
            SafetyPartImportResultDTO resultDTO = new SafetyPartImportResultDTO();
            resultDTO.setSuccessNumber(successNumber);
            resultDTO.setFailNumber(failedNumber);
            resultDTO.setImportResultList(list);
            return resultDTO;
        } catch (Exception e) {
            logger.error("导入模板失败", e);
            throw new BizException(ResultEnum.FAILURE.getCode(), "导入模板失败.");
        }
    }

    /**
     * 树形处理数据
     *
     * @param list 部位列表
     * @return 部位列表
     */
    private List<SafetyPartDTO> parseTree(List<SafetyPartDTO> list) {
        List<SafetyPartDTO> result = new ArrayList<>();

        // 1、获取第一级节点
        for (SafetyPartDTO safetyPartDTO : list) {
            if (0 == safetyPartDTO.getPid()) {
                result.add(safetyPartDTO);
            }
        }

        // 2、递归获取子节点
        for (SafetyPartDTO safetyPartDTO : result) {
            recursiveTree(safetyPartDTO, list);
        }

        return result;
    }

    /**
     * 递归获取子节点
     *
     * @param parent 父节点
     * @param list   部位列表
     */
    private void recursiveTree(SafetyPartDTO parent, List<SafetyPartDTO> list) {
        for (SafetyPartDTO safetyPartDTO : list) {
            if (parent.getPartId().equals(safetyPartDTO.getPid())) {
                recursiveTree(safetyPartDTO, list);
                List<SafetyPartDTO> children = parent.getChildren();
                if (children == null) {
                    children = new ArrayList<>();
                    parent.setChildren(children);
                }
                children.add(safetyPartDTO);
            }
        }
    }
}
